import java.util.ArrayList;
import java.util.ListIterator;


public class Assist {

	public static String manWay(Board b, PlayerNBoxesReverse pnb, ArrayList<Move> array){
		ListIterator<Move> itr = array.listIterator(0);
		String solution = "";
		Position target, targetBox;
		String oneWay;
		
		int max=array.size();
		
		for(int i=0;i<max;i++) {
			Move actualMove = array.get(i);
			
			//Find the target square
			targetBox = new Position(actualMove.getEnd());
			if (actualMove.getDirection() == Move.MOVE_DOWN)
				target = new Position(targetBox.getI()+1,targetBox.getJ());
			else if (actualMove.getDirection() == Move.MOVE_UP)
				target = new Position(targetBox.getI()-1,targetBox.getJ());
			else if (actualMove.getDirection() == Move.MOVE_RIGHT)
				target = new Position(targetBox.getI(),targetBox.getJ()+1);
			else
				target = new Position(targetBox.getI(),targetBox.getJ()-1);
			
			
			oneWay = PathFinding.pathTo(target, pnb, b);
			pnb = Assist.fakeBoxMove(pnb, actualMove);
			
			//System.out.println("the box @ is attempting to move " + targetBox.toString());
//			oneWay = PathFinding.pathTo(target, pnb, b);
			
			if (actualMove.getDirection() == Move.MOVE_UP)
				solution += oneWay+"D ";
			else if (actualMove.getDirection() == Move.MOVE_DOWN)
				solution += oneWay+"U ";
			else if (actualMove.getDirection() == Move.MOVE_LEFT)
				solution += oneWay+"R ";
			else
				solution += oneWay+"L ";
			//System.out.println("the Path              " + oneWay);
			
		
			//System.out.println("the Path + correct push" + solution);
		}
		
		
		
		return solution;
	}
	public static String arrayToString(int[][] array)
	{
		String pr="";
	    //int row=array.length;
		for (int[] row : array) {
            for (int val : row) {
                pr += " " + val;
            }
            pr += "\n";
        }
		return pr;
			
	}
	public static ArrayList<Move> possibleMoveBox(Board b, PlayerNBoxesReverse pnb) {
		ArrayList<Move> tab = new ArrayList<Move>();
		int i=0;
		int bestScore=100;
		int maxRows=b.getNumRows(),maxCols=b.getNumColumns();
		while(i<pnb.getBoxes().length){
			Position p = pnb.getBoxes()[i];
			// pull right
			
			if((p.getJ()+2)<maxCols)
			if ((b.getData(p.getI(),p.getJ()+1)&Board.WALL)==0
					&& pnb.getBoxAt(p.getI(),p.getJ()+1)==null
					&& (b.getData(p.getI(),p.getJ()+2)&Board.WALL)==0
					&& pnb.getBoxAt(p.getI(),p.getJ()+2)==null)
			{
				if (PathFinding.isPathTo(new Position(p.getI(),p.getJ()+1),pnb, b)){
					tab.add(new Move(p,Move.MOVE_RIGHT));
				}
				
			}
			
			//pull left
			if((p.getJ()-2)>=0)
			if ((b.getData(p.getI(),p.getJ()-1)&Board.WALL)==0
					&& pnb.getBoxAt(p.getI(),p.getJ()-1)==null
					&& (b.getData(p.getI(),p.getJ()-2)&Board.WALL)==0
					&& pnb.getBoxAt(p.getI(),p.getJ()-2)==null)
			{
				if (PathFinding.isPathTo(new Position(p.getI(),p.getJ()-1),pnb, b)){
					tab.add(new Move(p,Move.MOVE_LEFT));
				}
				
			}
			
			//pull up
			if((p.getI()-2)>=0)
			if ((b.getData(p.getI()-1,p.getJ())&Board.WALL)==0
					&& pnb.getBoxAt(p.getI()-1,p.getJ())==null
					&& (b.getData(p.getI()-2,p.getJ())&Board.WALL)==0
					&& pnb.getBoxAt(p.getI()-2,p.getJ())==null)
			{
				if (PathFinding.isPathTo(new Position(p.getI()-1,p.getJ()),pnb, b)){
					tab.add(new Move(p,Move.MOVE_UP));
				}
				
			}
			
			//pull down
			if((p.getI()+2)<maxRows)
			if ((b.getData(p.getI()+1,p.getJ())&Board.WALL)==0
					&& pnb.getBoxAt(p.getI()+1,p.getJ())==null
					&& (b.getData(p.getI()+2,p.getJ())&Board.WALL)==0
					&& pnb.getBoxAt(p.getI()+2,p.getJ())==null)
			{
				if (PathFinding.isPathTo(new Position(p.getI()+1,p.getJ()),pnb, b)){
					tab.add(new Move(p,Move.MOVE_DOWN));
				}
				
			}
			
			i++;
		}
		
		return tab;
	}
	
	public static boolean isItADeadlock(Board board, PlayerNBoxesReverse pnb)
	{
		
		int i=pnb.getPlayer().getI();
		int j=pnb.getPlayer().getJ();
          
		byte[][] jointedBoard = Helper.joinBoards(board, pnb);
		if(jointedBoard[i+1][j]==Board.EMPTY ||
				jointedBoard[i-1][j]==Board.EMPTY ||
				jointedBoard[i][j+1]==Board.EMPTY ||
				jointedBoard[i][j-1]==Board.EMPTY )
			return false;
		
		return true;
	}
	public static PlayerNBoxesReverse boxMove(PlayerNBoxesReverse pnb, Move m) {
		PlayerNBoxesReverse ans = new PlayerNBoxesReverse(pnb);
		ans.moveBox(m.getStart(), m.getEnd());
		int endI=m.getEnd().getI(),endJ=m.getEnd().getJ();
		//System.out.println();
		if(m.getDirection()==m.MOVE_RIGHT)
			endJ=endJ+1;
		if(m.getDirection()==m.MOVE_LEFT)
			endJ=endJ-1;
		if(m.getDirection()==m.MOVE_DOWN)
			endI=endI+1;
		if(m.getDirection()==m.MOVE_UP)
			endI=endI-1;
			
		Position plyr=new Position(endI,endJ);
		ans.setPlayer(plyr);
		
		return ans;
	}
	public static PlayerNBoxesReverse fakeBoxMove(PlayerNBoxesReverse pnb, Move m) {
		PlayerNBoxesReverse ans = new PlayerNBoxesReverse(pnb);
		ans.moveBox( m.getEnd(),m.getStart());
		int endI=m.getEnd().getI(),endJ=m.getEnd().getJ();
		
		if(m.getDirection()==m.MOVE_RIGHT)
			endJ=endJ+1;
		if(m.getDirection()==m.MOVE_LEFT)
			endJ=endJ-1;
		if(m.getDirection()==m.MOVE_DOWN)
			endJ=endI+1;
		if(m.getDirection()==m.MOVE_UP)
			endJ=endI-1;
			
		Position plyr=new Position(m.getEnd());
		ans.setPlayer(plyr);
		
		return ans;
	}
}
